package com.teemor.im.remoting.instance;

import com.teemor.im.common.cocurrent.FutureTaskScheduler;
import com.teemor.im.common.util.IOUtil;
import com.teemor.im.discovery.distributed.ImWorker;
import com.teemor.im.discovery.distributed.PeerManager;
import com.teemor.im.discovery.node.ServerNode;
import com.teemor.im.remoting.netty.CommandDispatcherHandler;
import com.teemor.im.remoting.netty.RmtMessageDecoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;

/**
 * @ename zhoulk
 * @cname 周李科
 * @date 2020/7/13 11:04
 */
public class NettyRemotingServer extends NettyRemotingAbstract {

    private final EventLoopGroup group = new NioEventLoopGroup();

    private int port;

    /**
     * @param permitsOneway 单向请求允许最大量
     * @param permitsAsync  异步请求运行最大量
     */
    public NettyRemotingServer(int permitsOneway, int permitsAsync, int port) {
        super(permitsOneway, permitsAsync);
        this.port = port;
    }

    @Override
    public ExecutorService callbackExecutor() {
        return null;
    }

    @Override
    protected Channel channel(ServerNode node) {
        return null;
    }

    @Override
    public void start() {
        ChannelFuture channelFuture = null;
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(group)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new StringEncoder());
//                        pipeline.addLast(new LineBasedFrameDecoder(1024 * 1024));
                        pipeline.addLast(new StringDecoder());
                        pipeline.addLast(new RmtMessageDecoder());

                        //命令分发handler
                        pipeline.addLast(new CommandDispatcherHandler(NettyRemotingServer.super.responseMap));
                    }
                });
        InetSocketAddress address = new InetSocketAddress(port);
        String ip = IOUtil.getHostAddress();
        channelFuture = bootstrap.bind(address);
        try {
            channelFuture.sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        ImWorker.getInst().setLocalNode(ip, port);
        NettyRemotingClient.instance().start();
        FutureTaskScheduler.add(() -> {
            /**
             * 启动节点
             */
            ImWorker.getInst().init();

            /**
             * 启动节点的管理
             */
            PeerManager.getInst().init();

        });
    }

    @Override
    public void stop() {

    }

    @Override
    public void restart() {

    }

    @Override
    public boolean isActive() {
        return false;
    }
}
